<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb>
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>商品管理</el-breadcrumb-item>
      <el-breadcrumb-item>分类参数</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片区域 -->
    <el-card>
      <!-- 头部的警告部分 -->
      <el-alert show-icon title="注意：只允许为第三级分类设置相关参数！" type="warning"></el-alert>
      <!-- 级联选择器的模块 -->
      <el-row class="noName">
        <el-col>
          <span>选择商品分类：</span>
          <!-- 级联选择框的部分 -->
          <!-- v-modle绑定的数据是选中的一级和二级商品分类的id  这是一个数组 -->
          <!-- option是数据源,指的是所有的一级和二级的商品分类数据 -->
          <!-- props是配置对象 -->
          <!-- @change是监听级联选择框里面的值,变化时触发 -->
          <el-cascader
            v-model="checkedCateArr"
            :options="dataCateList"
            :props="cascaderProps"
            @change="handleChange"
          ></el-cascader>
        </el-col>
      </el-row>
      <!-- Tab栏切换模块 -->
      <el-tabs v-model="activeName" @tab-click="tabCheckedClick">
        <!-- 动态参数 -->
        <el-tab-pane label="动态参数" name="many">
          <el-button type="primary" :disabled="isDisabled" size="mini" @click="addParams">添加参数</el-button>
          <!-- 动态参数的表格区域 -->
          <el-table :data="manyParamsList" stripe border>
            <!-- 添加展开列 -->
            <el-table-column type="expand">
              <!-- 添加参数的标签,这里要使用作用域插槽的方式 -->
              <template slot-scope="scope">
                <el-tag
                  v-for="(item,index) in scope.row.attr_vals"
                  :key="index"
                  closable
                  @close="delParams(index,scope.row)"
                >{{item}}</el-tag>
                <!-- 输入的文本框 -->
                <el-input
                  class="input-new-tag"
                  v-if="scope.row.inputVisible"
                  v-model="scope.row.inputValue"
                  ref="saveTagInput"
                  size="small"
                  @keyup.enter.native="handleInputConfirm(scope.row)"
                  @blur="handleInputConfirm(scope.row)"
                ></el-input>
                <!-- 添加的按钮 -->
                <el-button
                  v-else
                  class="button-new-tag"
                  size="small"
                  @click="showInput(scope.row)"
                >+ New Tag</el-button>
              </template>
            </el-table-column>
            <!-- 添加索引列 -->
            <el-table-column type="index"></el-table-column>
            <el-table-column prop="attr_name" label="参数名称"></el-table-column>
            <el-table-column label="操作">
              <!-- 这里用到了作用域的插槽 -->
              <template slot-scope="scope">
                <el-button
                  type="warning"
                  icon="el-icon-edit"
                  size="mini"
                  @click="showEditDialogVisible(scope.row.attr_id)"
                >修改</el-button>
                <el-button
                  type="danger"
                  icon="el-icon-delete"
                  size="mini"
                  @click="delCateParams(scope.row.attr_id)"
                >删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        <!-- 静态属性 -->
        <el-tab-pane label="静态属性" name="only">
          <el-button type="primary" :disabled="isDisabled" size="mini" @click="addParams">添加属性</el-button>
          <!-- 静态参数的表格区域 -->
          <el-table :data="onlyParamsList" stripe border>
            <!-- 添加展开列 -->
            <el-table-column type="expand">
              <!-- 添加参数的标签,这里要使用作用域插槽的方式 -->
              <template slot-scope="scope">
                <el-tag
                  v-for="(item,index) in scope.row.attr_vals"
                  :key="index"
                  closable
                  @close="delParams(index,scope.row)"
                >{{item}}</el-tag>
                <!-- 输入的文本框 -->
                <el-input
                  class="input-new-tag"
                  v-if="scope.row.inputVisible"
                  v-model="scope.row.inputValue"
                  ref="saveTagInput"
                  size="small"
                  @keyup.enter.native="handleInputConfirm(scope.row)"
                  @blur="handleInputConfirm(scope.row)"
                ></el-input>
                <!-- 添加的按钮 -->
                <el-button
                  v-else
                  class="button-new-tag"
                  size="small"
                  @click="showInput(scope.row)"
                >+ New Tag</el-button>
              </template>
            </el-table-column>
            <!-- 添加索引列 -->
            <el-table-column type="index"></el-table-column>
            <el-table-column prop="attr_name" label="参数名称"></el-table-column>
            <el-table-column label="操作">
              <!-- 这里用到了作用域的插槽 -->
              <template slot-scope="scope">
                <el-button
                  type="warning"
                  icon="el-icon-edit"
                  size="mini"
                  @click="showEditDialogVisible(scope.row.attr_id)"
                >修改</el-button>
                <el-button
                  type="danger"
                  icon="el-icon-delete"
                  size="mini"
                  @click="delCateParams(scope.row.attr_id)"
                >删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>
    </el-card>
    <!-- 添加参数的弹出会话框,这里把添加动态参数和静态属性共用同一个会话框 -->
    <el-dialog
      :title="'添加'+titleText"
      :visible.sync="addParamsDialogVisible"
      @close="resetFormAbility"
    >
      <!-- 表单部分 -->
      <el-form
        :model="addParamsForm"
        :rules="addParamsFormRules"
        ref="addParamsFormRef"
        label-width="100px"
      >
        <el-form-item :label="titleText" prop="attr_name">
          <el-input v-model="addParamsForm.attr_name"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="addParamsDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addCateParamsLast">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 修改参数的弹出会话框,这里还是两个共用一个 -->
    <el-dialog
      :title="'修改'+titleText"
      :visible.sync="editParamsDialogVisible"
      @close="resetEditParams"
    >
      <!-- 表单部分 -->
      <el-form
        :model="editParamsForm"
        :rules="editParamsFormRules"
        ref="editParamsFormRef"
        label-width="100px"
      >
        <el-form-item :label="titleText" prop="attr_name">
          <el-input v-model="editParamsForm.attr_name"></el-input>
        </el-form-item>
      </el-form>

      <div slot="footer" class="dialog-footer">
        <el-button @click="editParamsDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="editParamsLast">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
export default {
  data() {
    return {
      // 级联选择框的数据源
      dataCateList: [],
      //级联选择筐的props的配置对象
      cascaderProps: {
        value: "cat_id",
        label: "cat_name",
        children: "children",
        // 触发的方式
        expandTrigger: "hover",
        checkStrictly: true,
      },
      //选中分类项对应的id数组
      checkedCateArr: [],
      //   tab栏的绑定数据, 监听切换name的值
      activeName: "many",
      //动态参数的数据源
      manyParamsList: [],
      // 静态属性的数据源
      onlyParamsList: [],
      //   控制添加参数会话框的显示与隐藏
      addParamsDialogVisible: false,
      //   添加参数会话框的表单数据
      addParamsForm: {
        attr_name: "",
      },
      //   添加参数会话框的表单的验证规则
      addParamsFormRules: {
        // 参数的验证
        attr_name: [
          {
            required: true,
            message: "请输入参数名称!",
            trigger: "blur",
          },
        ],
      },
      //   这是控制修改参数弹出框的显示与隐藏
      editParamsDialogVisible: false,
      //   修改参数会话框的表单数据
      editParamsForm: {
        attr_name: "",
      },
      //   修改参数表单的验证
      editParamsFormRules: {
        // 验证规则
        attr_name: [
          { required: true, message: "请输入活动参数名称", trigger: "blur" },
        ],
      },
      // tido
    };
  },
  created: function () {
    //   生命周期函数
    this.getCateList();
  },
  methods: {
    //获取所有商品分类列表的函数
    getCateList: async function () {
      // 调接口
      const { data: res } = await this.$http.get("categories", {
        params: { type: 3 },
      });

      if (res.meta.status !== 200) {
        return this.$message.error("获取商品分类列表失败!");
      }

      this.$message.success(res.meta.msg);
      //   完成赋值的操作
      this.dataCateList = res.data;
    },
    // 级联选择框选项变化时 触发的函数
    handleChange: function () {
      //   如果级联选择框 选择的不是三级分类  则清空存放分类id的数组
      if (this.checkedCateArr.length !== 3) {
        //把存放分类名称id的数组清空
        this.checkedCateArr = [];
        return;
      }
      //   级联选择框选中三级分类的时候,也会调用这个获取参数列表的函数
      this.getCateParams();
    },
    // tab栏的模块 tab切换的时候会触发这个函数
    tabCheckedClick: function () {
      //   tab栏切换的时候,调用获取参数列表的函数
      this.getCateParams();
    },
    // 定义一个获取商品参数列表的函数
    getCateParams: async function () {
      // 判断是否为三级分类
      if (this.checkedCateArr.length !== 3) {
        this.checkedCateArr = [];
        return;
      }
      // 调接口
      const { data: res } = await this.$http.get(
        `categories/${this.cateId}/attributes`,
        {
          params: { sel: this.activeName },
        }
      );
      // 遍历res.data中的每一项,把attr_vals转换为数组,
      res.data.forEach((item) => {
        item.attr_vals = item.attr_vals ? item.attr_vals.split(",") : []; //如果有东西就转换为数组,如果没有就赋值一个空的数组
        // 为每一行的数据新增2个属性
        item.inputVisible = false; //默认隐藏展开列的文本框
        item.inputValue = ""; //默认与展开列的文本框绑定的值为空
      });

      //   因为有动态参数和静态属性公用一个返回的数据,因此这里要分开赋值
      if (this.activeName === "many") {
        this.manyParamsList = res.data; //动态赋值
      } else {
        this.onlyParamsList = res.data; //静态的赋值
      }
      console.log(res.data);
    },
    // 添加参数的相关处理函数
    addParams: function () {
      //点击显示会话框
      this.addParamsDialogVisible = true;
    },
    // 添加参数会话框表单的重置功能
    resetFormAbility: function () {
      this.$refs.addParamsFormRef.resetFields();
    },
    // 点击确定调接口,发送请求添加参数
    addCateParamsLast: function () {
      //提交前的预验证
      this.$refs.addParamsFormRef.validate(async (valid) => {
        if (valid) {
          //如果预验证通过,则调用接口
          const { data: res } = await this.$http.post(
            `categories/${this.cateId}/attributes`,
            {
              attr_name: this.addParamsForm.attr_name,
              attr_sel: this.activeName,
            }
          );

          if (res.meta.status !== 201) {
            return this.$message.error("添加参数失败!");
          }

          this.$message.success(res.meta.msg);
          //   重新获取参数的列表  ,并且关闭会话框
          this.getCateParams();
          this.addParamsDialogVisible = false;
        }
      });
    },
    // 根据id查询参数的 调用接口 相关处理函数
    showEditDialogVisible: async function (id) {
      //这个id是要修改参数的id
      this.editParamsDialogVisible = true;
      // 根据id来查询对应的分类名称,在重新渲染表单中
      //    调接口
      const { data: res } = await this.$http.get(
        `categories/${this.cateId}/attributes/${id}`
      );

      if (res.meta.status !== 200) {
        return this.$message.error("修改参数失败!");
      }

      this.$message.success(res.meta.msg);
      //   完成赋值的操作
      this.editParamsForm = res.data;
    },
    // 监听会话框的关闭,重置功能
    resetEditParams: function () {
      this.$refs.editParamsFormRef.resetFields();
    },
    // 点击确定,发起修改参数的接口请求
    editParamsLast: async function () {
      //   调接口
      const { data: res } = await this.$http.put(
        `categories/${this.cateId}/attributes/${this.editParamsForm.attr_id}`,
        {
          attr_name: this.editParamsForm.attr_name,
          attr_sel: this.activeName,
        }
      );

      if (res.meta.status !== 200) return this.$message.error("修改参数失败!");

      this.$message.success(res.meta.msg);
      //   重新获取参数列表的函数  同时关闭会话框
      this.getCateParams();
      this.editParamsDialogVisible = false;
    },
    // 删除的操作
    delCateParams: async function (id) {
      //   弹出框
      const result = await this.$prompt(
        "此操作将永久删除该参数, 是否继续?",
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
          // 捕获用户点击取消时的错误
        }
      ).catch(function (error) {
        return error;
      });
      //   判断result的返回值
      if (result === "cancel") {
        return this.$message({
          type: "info",
          message: "已取消删除",
        });
      }

      if (result === "confirm") {
        //   这是用户确定删除了,调用接口
        const { data: res } = await this.$http.delete(
          `categories/${this.cateId}/attributes/${id}`
        );
        if (res.meta.status !== 200) return this.$message.error("删除失败!");

        this.$message.success(res.meta.msg);

        // 重新获取参数列表
        this.getCateParams();
      }
    },
    // todo...
    // 展开列文本框失去焦点 相关的处理函数
    handleInputConfirm: async function (params) {
      // 失去焦点的时候,文本框隐藏
      // params.inputVisible = false;
      //  当用户输入的东西去掉左右的空格后,长度为0的时候，这是不行的,这时清空文本框的内容,同时隐藏文本框
      if (params.inputValue.trim().length === 0) {
        params.inputValue = "";
        params.inputVisible = false;
        return;
      }
      // 如果输入的有东西,这是就要调用编辑提交参数的接口了
      //  把用户输入的新的参数,追加到attr_vals里面,在统一的发起接口的请求

      params.attr_vals.push(params.inputValue.trim());
      params.inputValue = ""; //清空输入框的内容
      params.inputVisible = false; //关闭文本的输入框

      const { data: res } = await this.$http.put(
        `categories/${this.cateId}/attributes/${params.attr_id}`,
        {
          attr_name: params.attr_name,
          attr_sel: params.attr_sel,
          attr_vals: params.attr_vals.join(","), //不要忘记数组转字符串
        }
      );

      if (res.meta.status !== 200) {
        return this.$message.error("提交参数失败!");
      }

      this.$message.success(res.meta.msg);
      // 添加完毕后,重新获取一下参数的列表
      // this.getCateParams();
    },
    //点击按钮时的相关处理函数
    showInput: function (params) {
      // 显示文本框
      params.inputVisible = true;
      // 点击后,让文本框自动获取焦点
      this.$nextTick(() => {
        this.$refs.saveTagInput.$refs.input.focus();
      });
    },
    // 删除参数的相关处理函数
    delParams: async function (index, params) {
      // 发起请求之前的数据梳理 这种方法是以通过修改attr_vals数组里面的值 来间接删除的
      params.attr_vals.splice(index, 1); //把要删除的参数现在这个数组中删除,然后在重新调用编辑提交参数的接口
      // 调接口
      const { data: res } = await this.$http.put(
        `categories/${this.cateId}/attributes/${params.attr_id}`,
        {
          attr_name: params.attr_name,
          attr_sel: params.attr_sel,
          attr_vals: params.attr_vals.join(","), //不要忘记数组转字符串
        }
      );

      if (res.meta.status !== 200) {
        return this.$message.error("提交参数失败!");
      }

      this.$message.success(res.meta.msg);
    },
  },
  //   搞一个计算属性
  computed: {
    // 来控制添加参数按钮和添加属性按钮的禁用与否
    isDisabled: function () {
      if (this.checkedCateArr.length !== 3) {
        return true;
      } else {
        return false;
      }
    },
    // 这是过去商品分类的id 这里指的是选中的三级分类的id
    cateId: function () {
      // 判断存放分类id的数组长度 ，如果长度为3 则最后一个就是分类的id
      if (this.checkedCateArr.length === 3) {
        return this.checkedCateArr[2];
      } else {
        return null;
      }
    },
    // 这是添加动态参数和静态属性共用会话框的提示文本部分
    titleText: function () {
      if (this.activeName === "many") {
        return "动态参数";
      } else {
        return "静态属性";
      }
    },
  },
};
</script>
<style lang="less" scoped>
.noName {
  margin: 15px 0px;
}
.el-tag {
  margin: 10px;
}
.input-new-tag {
  width: 120px;
}
</style>